package com.dura.api.controller;

import com.dura.api.enums.SmsCodeEnum;
import com.dura.api.filter.CheckFilterContext;
import com.dura.api.form.SingleSendForm;
import com.dura.api.util.R;
import com.dura.api.vo.ResultVO;
import com.dura.common.constant.RabbitMQConstants;
import com.dura.common.model.StandardSubmit;
import com.dura.api.util.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;


/**
 * @version 1.0
 * @Author 振鹏
 * @Date 2025/3/15 9:46
 * @注释
 */
@RestController
@RequestMapping("/sms")
@Slf4j
public class SmsController {

    /**
     * 客户端IP地址 的请求头信息，用多个，隔开
     */
    @Value("${headers}")
    private String headers;

    /**
     * 基于请求头获取信息时，可能获取到的未知信息
     */
    private final String UNKNOW = "unknow";

    /**
     * 如果是当前请求头获取IP地址，需要截取到第一个','未知
     */
    private final String X_FORWARDED_FOR = "x-forwarded-for";

    /**
     * 校验链上下文
     */
    @Autowired
    private CheckFilterContext checkFilterContext;

    /**
     * 雪花算法
     */
    @Autowired
    private SnowFlakeUtil snowFlakeUtil;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @PostMapping(value = "/single-send",produces = "application/json;charset=utf-8")
    public ResultVO singleSend(@RequestBody @Validated SingleSendForm singleSendForm, BindingResult bindingResult, HttpServletRequest req){
        System.out.println("====================================");
        if(bindingResult.hasErrors()){
            String msg=bindingResult.getFieldError().getDefaultMessage();
            log.info("【接口模块-单条短信Controller】参数不合法"+msg);
            return R.error(SmsCodeEnum.PARAMETER_ERROR.getCode(),SmsCodeEnum.PARAMETER_ERROR.getMsg());
        }
        System.out.println("====================================");

        // ========获取真实的IP地址
        String ip=this.getRealIP(req);
        System.out.println("====================================  ip = "+ip);

        // ========构建StandardSubmit，各种封装校验==============
        StandardSubmit submit=new StandardSubmit();
        submit.setRealIP(ip);
        submit.setMobile(singleSendForm.getMobile());
        submit.setApikey(singleSendForm.getApikey());
        submit.setText(singleSendForm.getText());
        submit.setState(singleSendForm.getState());
        submit.setUid(singleSendForm.getUid());

        checkFilterContext.check(submit);
        //========================基于雪花算法生成唯一id，并添加到StandardSubmit对象中=========================================
        submit.setSequenceId(snowFlakeUtil.nextId());
        submit.setSendTime(LocalDateTime.now());

        //=========================发送到MQ，交给策略模块处理=========================================
        rabbitTemplate.convertAndSend(RabbitMQConstants.SMS_PRE_SEND,submit,new CorrelationData(submit.getSequenceId().toString()));

        // =====================没有问题，返回接收成功===============================
        return R.ok();
    }


    /**
     * 获取真实的IP地址
     * @param req
     * @return
     */
    private String getRealIP(HttpServletRequest req) {
        // 1. 声明返回的IP地址
        String ip;

        // 2.遍历请求头，并且通过req获取IP地址
        for(String header:headers.split(",")){
            if(!StringUtils.isEmpty(header)){
                // 基于req获取IP地址
                ip=req.getHeader(header);
                if(!StringUtils.isEmpty(ip) && !UNKNOW.equalsIgnoreCase(ip)){
                    // 判断请求头是否是x-forwarded-for （只有一条IP直接返回）
                    if(X_FORWARDED_FOR.equalsIgnoreCase(header) &&ip.indexOf(",")>0){
                        ip=ip.substring(0,ip.indexOf(","));
                    }
                    //返回IP地址
                    return ip;
                }
            }
        }

        // 如果请求头中都没有获取到IP地址，直接基于传统的方式获取一个IP
        return req.getRemoteAddr();
    }
}
